#include "performance.h"
#include "ui_performance.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QPrintDialog>
#include <QTextDocument>
#include <QtMath>
#include "shadow.h"
#include "msgbox.h"
#include "logger.h"
#include "udiskexport.h"
#include "loading.h"
#include "voltagemeasure.h"
#include "flowmeasure.h"
#include "userlogger.h"
#include "authmanager.h"
#include "customprinter.h"
#include "translation.h"

#define VOLTAGE_TEST_TIMES 370
#define FLOW_TEST_TIMES(volume, flowRate) predictRuntimes(volume, flowRate)

static QString toString(const VoltTest &voltTest)
{
    return QString("%1(%2V, %3μs); %4(%5V, %6μs); %7(%8V, %9μs)")
            .arg(QObject::tr("Low")).arg(voltTest.lowVolt.setValue).arg(voltTest.lowPulseWidth.setValue)
            .arg(QObject::tr("Medium")).arg(voltTest.mediumVolt.setValue).arg(voltTest.mediumPulseWidth.setValue)
            .arg(QObject::tr("High")).arg(voltTest.highVolt.setValue).arg(voltTest.highPulseWidth.setValue);
}

static QString toString(const FlowTest &flowTest)
{
    return QString("%1(%2mL, %3ml/min)").arg(QObject::tr("Parameter")).arg(flowTest.volume).arg(flowTest.flow.setValue);
}

Performance::Performance(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Performance)
{
    ui->setupUi(this);
    ui->stackedWidget->setCurrentIndex(0);

    bdf = BllDataFlow::getInstance();
    sqlHelper = SqlHelper::getInstance();
    exportMgr = new UdiskExport(this);
    voltMeasureMgr = new VoltageMeasure(this);
    flowMeasureMgr = new FlowMeasure(this);

    //Signals and Slots
    connect(bdf, &BllDataFlow::setWidgetVisibleSignal,this,&Performance::setWidgetVisibleSlot);
    connect(bdf, &BllDataFlow::selectDateTimePickerSignal, this, &Performance::changeDateTime);
    connect(bdf, &BllDataFlow::generateAllHtmlSucceedSignal, this, &Performance::setReportHtml);
    connect(bdf, &BllDataFlow::setCurrentTimeSignal, this, &Performance::setCurrentTimeSlot);
    connect(exportMgr, &UdiskExport::done, this, &Performance::pdfSaveDone);
    connect(voltMeasureMgr, &IMeasure::progress, this, &Performance::voltTestProgress);
    connect(flowMeasureMgr, &IMeasure::progress, this, &Performance::flowTestProgress);

    //
    connect(bdf, &BllDataFlow::retranslateUiSignal, this, &Performance::retranslateUiSlot);
    connect(bdf, &BllDataFlow::buildFinishedSignal, this, &Performance::setWidgetParent);

    dateTimePicker = new DateTimePicker(nullptr, DateTimeType::Date | DateTimeType::Hour | DateTimeType::Minute);

    initWidget();
}

Performance::~Performance()
{
    delete ui;
}

void Performance::save(const QString &path)
{
    MyOffice().savePdf(path, contentHtml);
}

void Performance::setWidgetParent()
{
    voltTestRes->setParent(Project::Instance());
    flowTestRes->setParent(Project::Instance());
    testLoading->setParent(Project::Instance());
}

void Performance::on_btnVoltRec_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->pgVolt);
    bdf->setCurrentTime(TimeSetType::PERFORMANCE_VOLT);
}

void Performance::on_btnFlowRec_clicked()
{
    ui->stackedWidget->setCurrentWidget(ui->pgSpeed);
    bdf->setCurrentTime(TimeSetType::PERFORMANCE_FLOW);
}

void Performance::on_btnVoltReturn_clicked()
{
    ui->tblwVoltRecord->setRowCount(0);
    ui->stackedWidget->setCurrentIndex(0);
}

void Performance::on_btnVoltPrint_clicked()
{
    ShowPrintDialog(voltContentHtml, tr("Print Voltage pulse record"));
}

void Performance::on_btnVoltExport_clicked()
{
    Loading::showLoading(QColor(0,0,0,200), false, tr("exporting..."));
    UserLogger::log(tr("Export Voltage pulse record"));
    contentHtml = voltContentHtml;
    exportType = ReportType::PERF_VOLT_REPORT;
    exportMgr->exports(exportType, this);
    ui->btnVoltExport->setEnabled(false);
}

void Performance::on_btnFlowReturn_clicked()
{
    ui->tblwFlowRecord->setRowCount(0);
    ui->stackedWidget->setCurrentIndex(0);
}

void Performance::on_btnFlowPrint_clicked()
{
    ShowPrintDialog(flowContentHtml, tr("Print Flow Rate record"));
}

void Performance::on_btnFlowExport_clicked()
{
    Loading::showLoading(QColor(0,0,0,200), false, tr("exporting..."));
    UserLogger::log(tr("Export Flow Rate record"));

    contentHtml = flowContentHtml;
    exportType = ReportType::PERF_FLOW_REPORT;
    exportMgr->exports(exportType, this);
    ui->btnFlowExport->setEnabled(false);
}

void Performance::on_btnVoltTest_clicked()
{
    if (QMessageBox::Ok == MsgBox::warning(this, tr("Volt Test"), tr("Would you like to start?")))
    {
        voltTest = {};
        voltTest.datetime = currentDateTime();
        voltTest.username = currentUsername;
        voltTest.lowVolt.setValue = ui->lineLowVolt->value();
        voltTest.mediumVolt.setValue = ui->lineMediumVolt->value();
        voltTest.highVolt.setValue = ui->lineHighVolt->value();
        voltTest.lowPulseWidth.setValue = ui->lineLowPulseWidth->value();
        voltTest.mediumPulseWidth.setValue = ui->lineMediumPulseWidth->value();
        voltTest.highPulseWidth.setValue = ui->lineHighPulseWidth->value();

        UserLogger::log(QString("%1\n>%2").arg(tr("Start Voltage Pulse Test")).arg(toString(voltTest)));
        testLoading->start(VOLTAGE_TEST_TIMES, tr("Voltage Pulse Test"));
        voltMeasureMgr->measure(&voltTest);
    }
}

void Performance::on_btnFlowTest_clicked()
{
    MsgBox msgbox;
    msgbox.setTitle(tr("Flow Test Remind"));

    QString html = QString("<p style='text-align:center;'><span style='color: rgb(255, 0, 0); font-size: %1px;'>%2,<br>%3</span></p>")
            .arg((windowWidth >= 1280) ? 26 : 22)
            .arg(tr("Please confirm material"))
            .arg(tr("and add the amount of liquid!"));
    msgbox.hideInformation();
    msgbox.setText(html);

    int state = msgbox.exec();
    if (QMessageBox::Ok == state)
    {
        flowTest.datetime = currentDateTime();
        flowTest.username = currentUsername;
        flowTest.volume = ui->lineVolume->value();
        flowTest.flow.setValue = ui->lineFlow->value();

        UserLogger::log(QString("%1: %2").arg(tr("Start Flow Rate Test")).arg(toString(flowTest)));
        testLoading->start(FLOW_TEST_TIMES(flowTest.volume, flowTest.flow.setValue), tr("Flow Rate Test"));
        flowMeasureMgr->measure(&flowTest);
    }
}

void Performance::retranslateUiSlot()
{
    ui->retranslateUi(this);
    retranslateTable();
}

void Performance::setWidgetVisibleSlot(int permission)
{
    Q_UNUSED(permission)

    clearVoltageTable();
    clearFlowTable();
}

void Performance::initWidget()
{ 
    setShadow({ui->widget_10,ui->widget_11,ui->widget_12,ui->widget_13,ui->widget_20,ui->widget_16,ui->widget_17,ui->widget_19,ui->widget_21,ui->widget_4,ui->widget_23,ui->widget_24});

    voltTestRes = new VoltTestResult();
    flowTestRes = new FlowTestResult();
    testLoading = new TestLoading();

    if (windowWidth >= 1280) {
        ui->btnVoltRec->setMaximumWidth(160);
        ui->btnFlowRec->setMaximumWidth(160);
        ui->widget_16->setFixedWidth(250);
        ui->btnDatetimeVoltStart->setFixedWidth(250);
        ui->datetimeVoltStart->setFixedWidth(250);
        ui->widget_17->setFixedWidth(250);
        ui->btnDatetimeVoltEnd->setFixedWidth(250);
        ui->datetimeVoltEnd->setFixedWidth(250);

        ui->widget_19->setFixedWidth(250);
        ui->btnDatetimeFlowStart->setFixedWidth(250);
        ui->datetimeSpeedStart->setFixedWidth(250);
        ui->widget_21->setFixedWidth(250);
        ui->btnDatetimeFlowEnd->setFixedWidth(250);
        ui->datetimeSpeedEnd->setFixedWidth(250);
        testLoading->setFixedWidth(1280);
        testLoading->setFixedHeight(800);
    }

    initVoltTestTable();
    initFlowTestTable();

    ui->lineLowVolt->init(60, 200, 60);
    ui->lineMediumVolt->init(201, 400, 201);
    ui->lineHighVolt->init(401, 600, 401);

    ui->lineLowPulseWidth->init(10, 100000, 2000);
    ui->lineMediumPulseWidth->init(10, 100000, 2000);
    ui->lineHighPulseWidth->init(10, 100000, 2000);

    ui->lineVolume->init(3, 100, 10.0, 2);
    ui->lineFlow->init(1, 20, 4.71, 2);
}

QString Performance::generateVoltTestTable(const QList<VoltTest> &voltList)
{
    int i = 0;
    QString html;
    html += QString("<table width='100%' border='1' valign='middle' align='left' style='border-collapse:collapse;' bordercolor='gray'>");

    //tr = table row, th = table header
    html += "<tr style='background-color:gray'>";
    html += QString("<th rowspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th rowspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th rowspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th colspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th colspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th colspan = '2'>%1</th>").arg(voltTableHeader[i++]);
    html += "</tr>";
    html += "<tr style='background-color:gray'>";

    //Set
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);
    //Actual
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);
    //Deviation
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);
    html += QString("<th>%1</th>").arg(voltTableHeader[i++]);

    html += "</tr>";

    // 每页显示的表格行数
    const int firstPageTableRowCount = 14;
    const int resetPageTableRowCount = 15;

    //td = table data
    int dataRowCount = voltList.size();
    for (int r = 0; r < dataRowCount; r++) {
        html += "<tr>";

        html += QString("<td rowspan = '3'>%1</td>").arg(voltList[r].datetime);
        html += QString("<td rowspan = '3'>%1</td>").arg(voltList[r].username);

        html += QString("<td>%1</td>").arg(tr("Low"));

        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].lowVolt.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].lowPulseWidth.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].lowVolt.realValue, 1));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].lowPulseWidth.realValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].lowVolt.realValue - voltList[r].lowVolt.setValue) / voltList[r].lowVolt.setValue * 100, 1));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].lowPulseWidth.realValue - voltList[r].lowPulseWidth.setValue) / voltList[r].lowPulseWidth.setValue * 100, 1));

        html += "</tr><tr>";
        html += QString("<td>%1</td>").arg(tr("Medium"));

        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].mediumVolt.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].mediumPulseWidth.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].mediumVolt.realValue, 1));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].mediumPulseWidth.realValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].mediumVolt.realValue - voltList[r].mediumVolt.setValue) / voltList[r].mediumVolt.setValue * 100, 1));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].mediumPulseWidth.realValue - voltList[r].mediumPulseWidth.setValue) / voltList[r].mediumPulseWidth.setValue * 100, 1));

        html += "</tr><tr>";
        html += QString("<td>%1</td>").arg(QString(tr("High")));

        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].highVolt.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].highPulseWidth.setValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].highVolt.realValue, 1));
        html += QString("<td>%1</td>").arg(doubleToString(voltList[r].highPulseWidth.realValue, 0));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].highVolt.realValue - voltList[r].highVolt.setValue) / voltList[r].highVolt.setValue * 100, 1));
        html += QString("<td>%1</td>").arg(doubleToString((voltList[r].highPulseWidth.realValue - voltList[r].highPulseWidth.setValue) / voltList[r].highPulseWidth.setValue * 100, 1));

        html += "</tr>";

        int rowCount = r + 1;
        if ((rowCount - firstPageTableRowCount) % resetPageTableRowCount == 0)
        {// 强制分页，解决合并单元格显示错位
            html += "</table>";
            html += "<table><tr><td></td></tr><div STYLE='page-break-after: always;'></div></table>";
            html += QString("<table width='100%' border='1' valign='middle' align='left' style='border-collapse:collapse;' bordercolor='gray'>");
        }
    }
    html += "</table>";
    return html;
}

QString Performance::generateFlowTestTable(const QList<FlowTest> &flowList)
{
    int i = 0;
    QString html;
    html += QString("<table width='100%' border='1' valign='middle' align='left' style='border-collapse:collapse;' bordercolor='gray'>");

    //tr = table row, th = table header
    html += "<tr style='background-color:gray'>";
    html += QString("<th rowspan = '2'>%1</th>").arg(flowTableHeader[i++]);
    html += QString("<th rowspan = '2'>%1</th>").arg(flowTableHeader[i++]);
    html += QString("<th colspan = '2'>%1</th>").arg(flowTableHeader[i++]);
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);
    html += "</tr>";
    html += "<tr style='background-color:gray'>";

    //Set
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);
    //Actual
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);
    //Deviation
    html += QString("<th>%1</th>").arg(flowTableHeader[i++]);

    html += "</tr>";

    //td = table data
    int dataRowCount = flowList.size();
    for (int r = 0; r < dataRowCount; r++) {
        html += "<tr>";

        html += QString("<td>%1</td>").arg(flowList[r].datetime);
        html += QString("<td>%1</td>").arg(flowList[r].username);
        html += QString("<td>%1</td>").arg(doubleToString(flowList[r].volume, 2));
        html += QString("<td>%1</td>").arg(doubleToString(flowList[r].flow.setValue, 2));
        html += QString("<td>%1</td>").arg(doubleToString(flowList[r].flow.realValue, 2));
        html += QString("<td>%1</td>").arg(doubleToString((flowList[r].flow.realValue - flowList[r].flow.setValue) / flowList[r].flow.setValue * 100, 2));

        html += "</tr>";
    }
    html += "</table>";
    return html;
}



void Performance::initVoltTestTable()
{
    int headerRowCount = 2;
    int headerRowHeight = 42;   //todo:pixel

//    int contentRowCount = 2;  //no need, will be set after data query
    int contentColCount = 9;
    int contentRowHeight = 30;  //todo:pixel

    ui->tblwVoltRecord->setColumnNum(contentColCount);
    ui->tblwVoltRecord->setHeaderRowCount(headerRowCount);
    ui->tblwVoltRecord->setHeaderRowHeight(headerRowHeight);
    qDebug() << "initVoltTestTable:";
    ui->tblwVoltRecord->initWidget();

    QTableWidget * voltHeaderTable = ui->tblwVoltRecord->getHeaderTable();
    QTableWidget * voltContentTable = ui->tblwVoltRecord->getContentTable();


    //设定表头
    //===================设置header内容=================//
    //合并单元格
    voltHeaderTable->setSpan(0, 0, 2, 1); //测试时间
    voltHeaderTable->setSpan(0, 1, 2, 1); //操作人员
    voltHeaderTable->setSpan(0, 2, 2, 1); //类型
    voltHeaderTable->setSpan(0, 3, 1, 2); //设定参数
    voltHeaderTable->setSpan(0, 5, 1, 2); //实际参数
    voltHeaderTable->setSpan(0, 7, 1, 2); //偏差值

    voltTableHeader.clear();
    voltTableHeader.append(tr("Test Time"));
    voltTableHeader.append(tr("Operator"));
    voltTableHeader.append(tr("Type"));
    voltTableHeader.append(tr("SetParam"));
    voltTableHeader.append(tr("AcutalParam"));
    voltTableHeader.append(tr("Deviation"));
    voltTableHeader.append(tr("Voltage") + "(V)");
    voltTableHeader.append(tr("Pulse") + "(μs)");
    voltTableHeader.append(tr("Voltage") + "(V)");
    voltTableHeader.append(tr("Pulse") + "(μs)");
    voltTableHeader.append(tr("Voltage") + "(%)");
    voltTableHeader.append(tr("Pulse") + "(%)");

    int i = 0;
    voltHeaderTable->setItem(0, 0, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(0, 1, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(0, 2, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(0, 3, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(0, 5, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(0, 7, new QTableWidgetItem(voltTableHeader[i++]));

    voltHeaderTable->setItem(1, 3, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(1, 4, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(1, 5, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(1, 6, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(1, 7, new QTableWidgetItem(voltTableHeader[i++]));
    voltHeaderTable->setItem(1, 8, new QTableWidgetItem(voltTableHeader[i++]));

    // set first column width
    voltHeaderTable->setColumnWidth(0, 220);
    voltContentTable->setColumnWidth(0, 220);
}

void Performance::initFlowTestTable()
{
    int headerRowCount = 2;
    int headerRowHeight = 42;
    int contentColCount = 6;
    ui->tblwFlowRecord->setColumnNum(contentColCount);
    ui->tblwFlowRecord->setHeaderRowCount(headerRowCount);
    ui->tblwFlowRecord->setHeaderRowHeight(headerRowHeight);
    qDebug() << "initFlowTestTable:";
    ui->tblwFlowRecord->initWidget();

    QTableWidget * flowHeaderTable = ui->tblwFlowRecord->getHeaderTable();
    QTableWidget * flowContentTable = ui->tblwFlowRecord->getContentTable();


    //设定表头
    //===================设置header内容=================//
    //合并单元格
    flowHeaderTable->setSpan(0, 0, 2, 1);//测试时间
    flowHeaderTable->setSpan(0, 1, 2, 1);//操作人员
    flowHeaderTable->setSpan(0, 2, 1, 2);//设定参数

    flowTableHeader.clear();
    flowTableHeader.append(tr("Test Time"));
    flowTableHeader.append(tr("Operator"));
    flowTableHeader.append(tr("SetParam"));
    flowTableHeader.append(tr("AcutalParam"));
    flowTableHeader.append(tr("Deviation"));

    flowTableHeader.append(tr("Volume") + "(ml)");
    flowTableHeader.append(tr("Flow") + "(ml/min)");
    flowTableHeader.append(tr("Flow") + "(ml/min)");
    flowTableHeader.append(tr("Flow") + "(%)");

    int i = 0;
    flowHeaderTable->setItem(0, 0, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(0, 1, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(0, 2, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(0, 4, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(0, 5, new QTableWidgetItem(flowTableHeader[i++]));

    flowHeaderTable->setItem(1, 2, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(1, 3, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(1, 4, new QTableWidgetItem(flowTableHeader[i++]));
    flowHeaderTable->setItem(1, 5, new QTableWidgetItem(flowTableHeader[i++]));

    // set first column width
    flowHeaderTable->setColumnWidth(0, 240);
    flowHeaderTable->setColumnWidth(1, 140);
    flowHeaderTable->setColumnWidth(2, 140);
    flowHeaderTable->setColumnWidth(3, 140);
    flowHeaderTable->setColumnWidth(4, 140);
    flowHeaderTable->setColumnWidth(5, 140);
    flowContentTable->setColumnWidth(0, 240);
    flowContentTable->setColumnWidth(1, 140);
    flowContentTable->setColumnWidth(2, 140);
    flowContentTable->setColumnWidth(3, 140);
    flowContentTable->setColumnWidth(4, 140);
    flowContentTable->setColumnWidth(5, 140);
}

void Performance::retranslateTable()
{
    initVoltTestTable();
    initFlowTestTable();
}

void Performance::clearVoltageTable()
{
    voltContentHtml.clear();
    voltReportHtml.clear();

    ui->tblwVoltRecord->setRowCount(0);
    ui->btnVoltPrint->setEnabled(false);
    ui->btnVoltExport->setEnabled(false);
}

void Performance::clearFlowTable()
{
    flowContentHtml.clear();
    flowReportHtml.clear();

    ui->tblwFlowRecord->setRowCount(0);
    ui->btnFlowPrint->setEnabled(false);
    ui->btnFlowExport->setEnabled(false);
}

void Performance::on_btnVoltQuery_clicked()
{
    ui->btnVoltQuery->setEnabled(false);
    QString startDateTime = ui->datetimeVoltStart->dateTime().toString(FMT_S);
    QString endDateTime = ui->datetimeVoltEnd->dateTime().toString(FMT_S);
    QString user;
    if (AuthManager::instance()->isManufacturer(currentUsername))
    {// 厂家账号，可以查看所有测试记录
        user = "";
    }
    else if (AuthManager::instance()->isAdministrator(currentUsername))
    {// 管理员，过滤掉掉厂家测试记录
       user = "!=" + AuthManager::instance()->manufacturer();
    }
    else
    {// 普通用户，只能查看自己的测试记录
        user = currentUsername;
    }

    voltList = sqlHelper->selectVoltTestBasedOnTime(startDateTime, endDateTime, user);
    int count = voltList.size();
    UserLogger::log(QString("%1%2~%3%4\n>%5: %6").arg(tr("Query")).arg(startDateTime).arg(endDateTime).arg(tr("Voltage pulse record")).arg(tr("Records Count")).arg(count));

    ui->tblwVoltRecord->clearContents();
    if (count == 0) {
        clearVoltageTable();
        ui->tblwVoltRecord->setRowCount(1);
        ui->tblwVoltRecord->setRowHeight(0, windowWidth >= 1280 ? 300 : 220);
        ui->tblwVoltRecord->setSpan(0,0,1,11);
        ui->tblwVoltRecord->setShowGrid(false);
        QTableWidgetItem * item = new QTableWidgetItem(tr("No data yet"));
        item->setTextAlignment(Qt::AlignCenter);
        ui->tblwVoltRecord->setItem(0,0,item);
        ui->btnVoltQuery->setEnabled(true);
        return;
    }

    ui->btnVoltPrint->setEnabled(true);
    ui->btnVoltExport->setEnabled(true);
    ui->tblwVoltRecord->setShowGrid(true);
    ui->tblwVoltRecord->setSpan(0,0,1,1);
    ui->tblwVoltRecord->setRowCount(count * 3);

    int contentRowHeight = 50;
    for (int r = 0; r < count; r++)
    {
        ui->tblwVoltRecord->setSpan(r * 3, 0, 3, 1);
        ui->tblwVoltRecord->setSpan(r * 3, 1, 3, 1);
        ui->tblwVoltRecord->setRowHeight(r * 3,contentRowHeight);
        ui->tblwVoltRecord->setRowHeight(r * 3 + 1,contentRowHeight);
        ui->tblwVoltRecord->setRowHeight(r * 3 + 2,contentRowHeight);

        QTableWidgetItem * datetimeItem = new QTableWidgetItem(voltList[r].datetime);
        QTableWidgetItem * usernameItem = new QTableWidgetItem(voltList[r].username);
        QTableWidgetItem * lowTypeItem = new QTableWidgetItem(tr("Low"));
        QTableWidgetItem * mediumTypeItem = new QTableWidgetItem(tr("Medium"));
        QTableWidgetItem * highTypeItem = new QTableWidgetItem(tr("High"));

        // 设定参数的低中高电压值和脉冲
        QTableWidgetItem * lowSetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].lowVolt.setValue, 0));
        QTableWidgetItem * mediumSetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].mediumVolt.setValue, 0));
        QTableWidgetItem * highSetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].highVolt.setValue, 0));
        QTableWidgetItem * lowSetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].lowPulseWidth.setValue, 0));
        QTableWidgetItem * mediumSetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].mediumPulseWidth.setValue, 0));
        QTableWidgetItem * highSetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].highPulseWidth.setValue, 0));

        // 实际参数的低中高电压值和脉冲
        QTableWidgetItem * lowGetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].lowVolt.realValue, 1));
        QTableWidgetItem * mediumGetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].mediumVolt.realValue, 1));
        QTableWidgetItem * highGetVoltItem = new QTableWidgetItem(doubleToString(voltList[r].highVolt.realValue, 1));
        QTableWidgetItem * lowGetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].lowPulseWidth.realValue, 1));
        QTableWidgetItem * mediumGetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].mediumPulseWidth.realValue, 0));
        QTableWidgetItem * highGetPulseItem = new QTableWidgetItem(doubleToString(voltList[r].highPulseWidth.realValue, 0));

        // 偏差值的低中高电压值和脉冲
        QTableWidgetItem * lowVoltItem = new QTableWidgetItem(doubleToString((voltList[r].lowVolt.realValue - voltList[r].lowVolt.setValue) / voltList[r].lowVolt.setValue * 100, 1));
        QTableWidgetItem * mediumVoltItem = new QTableWidgetItem(doubleToString((voltList[r].mediumVolt.realValue - voltList[r].mediumVolt.setValue) / voltList[r].mediumVolt.setValue * 100, 1));
        QTableWidgetItem * highVoltItem = new QTableWidgetItem(doubleToString((voltList[r].highVolt.realValue - voltList[r].highVolt.setValue) / voltList[r].highVolt.setValue * 100, 1));
        QTableWidgetItem * lowPulseItem = new QTableWidgetItem(doubleToString((voltList[r].lowPulseWidth.realValue - voltList[r].lowPulseWidth.setValue) / voltList[r].lowPulseWidth.setValue * 100, 1));
        QTableWidgetItem * mediumPulseItem = new QTableWidgetItem(doubleToString((voltList[r].mediumPulseWidth.realValue - voltList[r].mediumPulseWidth.setValue) / voltList[r].mediumPulseWidth.setValue * 100, 1));
        QTableWidgetItem * highPulseItem = new QTableWidgetItem(doubleToString((voltList[r].highPulseWidth.realValue - voltList[r].highPulseWidth.setValue) / voltList[r].highPulseWidth.setValue * 100, 1));

        // 需要逻辑判断如果偏差值不等于0的item，则将文本标红
//        if (true) {
//            lowVoltItem->setTextColor(QColor(203,0,0,255));
//            highVoltItem->setTextColor(QColor(203,0,0,255));
//        }

        // 文本居中
        datetimeItem->setTextAlignment(Qt::AlignCenter);
        usernameItem->setTextAlignment(Qt::AlignCenter);
        lowTypeItem->setTextAlignment(Qt::AlignCenter);
        mediumTypeItem->setTextAlignment(Qt::AlignCenter);
        highTypeItem->setTextAlignment(Qt::AlignCenter);
        lowSetVoltItem->setTextAlignment(Qt::AlignCenter);
        mediumSetVoltItem->setTextAlignment(Qt::AlignCenter);
        highSetVoltItem->setTextAlignment(Qt::AlignCenter);
        lowSetPulseItem->setTextAlignment(Qt::AlignCenter);
        mediumSetPulseItem->setTextAlignment(Qt::AlignCenter);
        highSetPulseItem->setTextAlignment(Qt::AlignCenter);
        lowGetVoltItem->setTextAlignment(Qt::AlignCenter);
        mediumGetVoltItem->setTextAlignment(Qt::AlignCenter);
        highGetVoltItem->setTextAlignment(Qt::AlignCenter);
        lowGetPulseItem->setTextAlignment(Qt::AlignCenter);
        mediumGetPulseItem->setTextAlignment(Qt::AlignCenter);
        highGetPulseItem->setTextAlignment(Qt::AlignCenter);
        lowVoltItem->setTextAlignment(Qt::AlignCenter);
        mediumVoltItem->setTextAlignment(Qt::AlignCenter);
        highVoltItem->setTextAlignment(Qt::AlignCenter);
        lowPulseItem->setTextAlignment(Qt::AlignCenter);
        mediumPulseItem->setTextAlignment(Qt::AlignCenter);
        highPulseItem->setTextAlignment(Qt::AlignCenter);

        ui->tblwVoltRecord->setItem(r * 3, 0, datetimeItem);
        ui->tblwVoltRecord->setItem(r * 3, 1, usernameItem);

        ui->tblwVoltRecord->setItem(r * 3, 2, lowTypeItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 2, mediumTypeItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 2, highTypeItem);

        ui->tblwVoltRecord->setItem(r * 3, 3, lowSetVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 3, mediumSetVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 3, highSetVoltItem);

        ui->tblwVoltRecord->setItem(r * 3, 4, lowSetPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 4, mediumSetPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 4, highSetPulseItem);

        ui->tblwVoltRecord->setItem(r * 3, 5, lowGetVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 5, mediumGetVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 5, highGetVoltItem);

        ui->tblwVoltRecord->setItem(r * 3, 6, lowGetPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 6, mediumGetPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 6, highGetPulseItem);

        ui->tblwVoltRecord->setItem(r * 3, 7, lowVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 7, mediumVoltItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 7, highVoltItem);

        ui->tblwVoltRecord->setItem(r * 3, 8, lowPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 1, 8, mediumPulseItem);
        ui->tblwVoltRecord->setItem(r * 3 + 2, 8, highPulseItem);
    }

    voltContentHtml = generateVoltTestTable(voltList);
    bdf->generateAllHtml(ReportType::PERF_VOLT_REPORT, voltContentHtml);
    ui->btnVoltQuery->setEnabled(true);  
}

void Performance::on_btnFlowQuery_clicked()
{
    ui->btnFlowQuery->setEnabled(false);
    QString startDateTime = ui->datetimeSpeedStart->dateTime().toString(FMT_S);
    QString endDateTime = ui->datetimeSpeedEnd->dateTime().toString(FMT_S);
    QString user;
    if (AuthManager::instance()->isManufacturer(currentUsername))
    {// 厂家账号，可以查看所有测试记录
        user = "";
    }
    else if (AuthManager::instance()->isAdministrator(currentUsername))
    {// 管理员，过滤掉掉厂家测试记录
       user = "!=" + AuthManager::instance()->manufacturer();
    }
    else
    {// 普通用户，只能查看自己的测试记录
        user = currentUsername;
    }

    flowList = sqlHelper->selectFlowTestBasedOnTime(startDateTime, endDateTime, user);
    int count = flowList.size();
    UserLogger::log(QString("%1%2~%3%4\n>%5: %6").arg(tr("Query")).arg(startDateTime).arg(endDateTime).arg(tr("Flow Rate record")).arg(tr("Records Count")).arg(count));

    ui->tblwFlowRecord->clearContents();
    if (count == 0) {
        clearFlowTable();
        ui->tblwFlowRecord->setRowCount(1);
        ui->tblwFlowRecord->setRowHeight(0, windowWidth >= 1280 ? 300 : 220);
        ui->tblwFlowRecord->setSpan(0,0,1,8);
        ui->tblwFlowRecord->setShowGrid(false);
        QTableWidgetItem * item = new QTableWidgetItem(tr("No data yet"));
        item->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->setItem(0,0,item);
        ui->btnFlowQuery->setEnabled(true);
        return;
    }

    ui->btnFlowPrint->setEnabled(true);
    ui->btnFlowExport->setEnabled(true);
    ui->tblwFlowRecord->setShowGrid(true);
    ui->tblwFlowRecord->setSpan(0,0,1,1);
    ui->tblwFlowRecord->setRowCount(count);

    int contentRowHeight = 50;
    for (int r = 0;r < count;r++)
    {
        ui->tblwFlowRecord->setRowHeight(r,contentRowHeight);
        ui->tblwFlowRecord->setItem(r,0, new QTableWidgetItem(flowList[r].datetime));
        ui->tblwFlowRecord->setItem(r,1, new QTableWidgetItem(flowList[r].username));
        ui->tblwFlowRecord->setItem(r,2, new QTableWidgetItem(doubleToString(flowList[r].volume, 2)));
        ui->tblwFlowRecord->setItem(r,3, new QTableWidgetItem(doubleToString(flowList[r].flow.setValue, 2)));
        ui->tblwFlowRecord->setItem(r,4, new QTableWidgetItem(doubleToString(flowList[r].flow.realValue, 2)));
        ui->tblwFlowRecord->setItem(r,5, new QTableWidgetItem(doubleToString((flowList[r].flow.realValue - flowList[r].flow.setValue) / flowList[r].flow.setValue * 100, 2)));

        ui->tblwFlowRecord->item(r,0)->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->item(r,1)->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->item(r,2)->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->item(r,3)->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->item(r,4)->setTextAlignment(Qt::AlignCenter);
        ui->tblwFlowRecord->item(r,5)->setTextAlignment(Qt::AlignCenter);
    }

    flowContentHtml = generateFlowTestTable(flowList);
    bdf->generateAllHtml(ReportType::PERF_FLOW_REPORT, flowContentHtml);
    ui->btnFlowQuery->setEnabled(true);
}

void Performance::on_btnDatetimeVoltStart_clicked()
{
    dateTimePicker->show();
    dateTimePicker->setWhatsThis("performance_voltstart_datetimepicker");
    dateTimePicker->setDateTime(ui->datetimeVoltStart->dateTime());
}

void Performance::on_btnDatetimeVoltEnd_clicked()
{
    dateTimePicker->show();
    dateTimePicker->setWhatsThis("performance_voltend_datetimepicker");
    dateTimePicker->setDateTime(ui->datetimeVoltEnd->dateTime());
}

void Performance::on_btnDatetimeFlowStart_clicked()
{
    dateTimePicker->show();
    dateTimePicker->setWhatsThis("performance_flowstart_datetimepicker");
    dateTimePicker->setDateTime(ui->datetimeSpeedStart->dateTime());
}


void Performance::on_btnDatetimeFlowEnd_clicked()
{
    dateTimePicker->show();
    dateTimePicker->setWhatsThis("performance_flowend_datetimepicker");
    dateTimePicker->setDateTime(ui->datetimeSpeedEnd->dateTime());
}

void Performance::changeDateTime(QDateTime dateTime, QString whatsThis)
{
    if (whatsThis == "performance_voltstart_datetimepicker") {
        ui->datetimeVoltStart->setDateTime(dateTime);
    } else if (whatsThis == "performance_voltend_datetimepicker") {
        ui->datetimeVoltEnd->setDateTime(dateTime);
    } else if (whatsThis == "performance_flowstart_datetimepicker") {
        ui->datetimeSpeedStart->setDateTime(dateTime);
    } else if (whatsThis == "performance_flowend_datetimepicker") {
        ui->datetimeSpeedEnd->setDateTime(dateTime);
    }
}

void Performance::setReportHtml(int type, const QString html)
{
    if(ReportType::PERF_VOLT_REPORT == type)
    {
        voltReportHtml = html;
    }
    else if (ReportType::PERF_FLOW_REPORT == type)
    {
        flowReportHtml = html;
    }
}

void Performance::setCurrentTimeSlot(int type)
{
    QDateTime dateTime = QDateTime::currentDateTime();
    if(TimeSetType::PERFORMANCE_VOLT == type)
    {
        ui->datetimeVoltEnd->setDateTime(dateTime);
    }
    else if (TimeSetType::PERFORMANCE_FLOW == type) {
        ui->datetimeSpeedEnd->setDateTime(dateTime);
    }
}

void Performance::pdfSaveDone(const QString &info, const QString &path)
{
    static const QMap<ReportType, QString> mapper = {
        {ReportType::PERF_FLOW_REPORT, tr("PerformanceFlowReport")},
        {ReportType::PERF_VOLT_REPORT, tr("PerformanceVoltReport")},
    };

    if (!mapper.contains(exportType))
    {
        return;
    }

    UserLogger::log(info);

    MsgBox msgBox;
    msgBox.setTitle(Tr(mapper[exportType]));
    msgBox.setText(info);
    msgBox.setInformativeText(path);
    msgBox.setBtnCancelVisible(false);
    msgBox.exec();

    ui->btnFlowExport->setEnabled(true);
    ui->btnVoltExport->setEnabled(true);
    Loading::hideLoading();
}

void Performance::voltTestProgress(const QString &info, bool stopped)
{
    UserLogger::log(info);
    testLoading->updateTips(info);

    if (stopped)
    {
        sqlHelper->insertVoltTestResult(voltTest);
        testLoading->stop();
        voltTestRes->show(voltTest);
    }
}

void Performance::flowTestProgress(const QString &info, bool stopped)
{
    UserLogger::log(info);

    if (stopped)
    {
        sqlHelper->insertFlowTestResult(flowTest);
        testLoading->stop();
        flowTestRes->show(flowTest);
    }
}

